﻿using NoDriverPrintHelperV1d0.Singleton;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using ZhangLogSysV1d0;

namespace NoDriverPrintHelperV1d0.Entity
{
    //愛普生TM-220打印機Esc打印函數
    public class TmU220EscPosPrintFunctionV1d0
    {
        /// <summary>
        /// 打印機IP地址
        /// </summary>
        public string PrinterNetIp { get; set; }
        /// <summary>
        /// 打印機端口號
        /// </summary>
        public int PrinterNetPort { get; set; }
        /// <summary>
        /// 打印機Tcp客戶端連接套接字
        /// </summary>
        public TcpClient PrinterTcpClient { get; set; }
        /// <summary>
        /// 打印機連接超時時間
        /// </summary>
        public int ConnectTimeoutSecond { get; set; }
        /// <summary>
        /// 打印機常駐漢字字符類別
        /// </summary>
        public string PrinterResidentChineseCharacter { get; set; }
        /// <summary>
        /// 紙寬
        /// </summary>
        public int PaperWidth { get; set; }
        /// <summary>
        /// 字符間隔
        /// </summary>
        public int DotSpaceBetweenCharacter { get; set; }
        /// <summary>
        /// 每行的字符個數
        /// </summary>
        public int CharactersPerLine { get; set; }


        public TmU220EscPosPrintFunctionV1d0(TcpClient tcpClient)
        {
            PrinterNetIp = "192.168.3.99";
            PrinterNetPort = 9100;
            PrinterTcpClient = null;
            PrinterResidentChineseCharacter = "Triditional";
            PaperWidth = 76;
            DotSpaceBetweenCharacter = 3;
            CharactersPerLine = 40;
            ConnectTimeoutSecond = 3;
            PrinterTcpClient = tcpClient;
        }

        private void DisConnnect()
        {
            if (PrinterTcpClient != null)
                PrinterTcpClient.Close();
        }
        /// <summary>
        /// 发送自己指令到打印机
        /// </summary>
        /// <param name="command">字节指令</param>
        /// <returns></returns>
        public bool SendByteCommand(byte[] command)
        {
            bool isSuccess = false;
            try
            {
                if (PrinterTcpClient!=null&&PrinterTcpClient.Connected)
                {
                    NetworkStream netStream = PrinterTcpClient.GetStream();
                    netStream.Write(command, 0, command.Length);
                    netStream.Flush();

                    isSuccess = true;
                }                
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
                isSuccess = false;
            }
            return isSuccess;
        }


        /// <summary>
        /// 发送字符串打打印机
        /// </summary>
        /// <param name="content">待打印字符串</param>
        /// <param name="encodingName">待打印机字符串的编码名称</param>
        /// <returns></returns>
        public bool SendStringToPrinter(string content,string encodingName="Big5")
        {
            bool isSuccess = false;
            try
            {
                Encoding currEncoding=Encoding.GetEncoding(encodingName);
                byte[] printByteArray = currEncoding.GetBytes(content);
                isSuccess=SendTextByteArrayToPrinter(printByteArray);
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }

        /// <summary>
        /// 将文本的已编码字节数组发送至打印机
        /// </summary>
        /// <param name="textBytes">文本字节数据</param>
        /// <returns></returns>
        private bool SendTextByteArrayToPrinter(byte[] textBytes)
        {
            bool isSuccess = false;
            try
            {
                if (PrinterTcpClient.Connected)
                {
                    NetworkStream netStream = PrinterTcpClient.GetStream();
                    netStream.Write(textBytes, 0, textBytes.Length);
                    netStream.Flush();
                    isSuccess = true;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }

        /// <summary>
        /// 打印位图
        /// </summary>
        /// <param name="bitmap">400像素宽，高度为8的整倍数</param>
        /// <returns></returns>
        public bool SendBitmpToPrinter(Bitmap bitmap)
        {
            bool result = false;
            try
            {
                bool isCorrect = CheckBitmapFormat(bitmap);
                if (isCorrect == false) return false;
                else
                {
                    int bitmapHeight = bitmap.Height;
                    int rowCount = bitmapHeight / 8;//行高度8个像素
                    for (int i = 0; i < rowCount; i++)
                    {
                        SendRowOfBitmapToPrinter(i, bitmap);
                        //12个打印机垂直运动单位
                        byte TMU220B_VerticalMoveUnits = 12;
                        //打印机走纸12个垂直运动单位
                        SendByteCommand(PrinterCmdUtilsV1d0.printAndFeedPaper_VerticalUnit(TMU220B_VerticalMoveUnits));
                    }
                    return true;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return result;

        }

        /// <summary>
        /// 8点双密度打印位图的指定行
        /// </summary>
        /// <param name="rowIndex">行序号</param>
        /// <param name="bitmap">待打印位图</param>
        public void SendRowOfBitmapToPrinter(int rowIndex, Bitmap bitmap)
        {
            bool isCorrect = CheckBitmapFormat(bitmap);
            try
            {
                if (isCorrect)
                {
                    //将位图指定行转换成,打印机的位图字节数组
                    byte[] bitmapByteArray = PrinterCmdUtilsV1d0.pic2PxPoint8NeedleDoubleDensity(bitmap, rowIndex);
                    if (PrinterTcpClient != null && PrinterTcpClient.Connected)
                    {
                        NetworkStream netStream = PrinterTcpClient.GetStream();
                        netStream.Write(bitmapByteArray, 0, bitmapByteArray.Length);
                        netStream.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
        }

        /// <summary>
        /// 发送打印任务项到打印机
        /// </summary>
        /// <param name="taskItem"></param>
        /// <returns></returns>
        public bool SendPrintTaskItemToPrinter(PrintTaskItemV1d0 taskItem)
        {
            bool isSuccess = false;
            try
            {
                if (taskItem.content_text.Length == 0) return false;
                if (taskItem.TextFormat.print_mode == "Text")
                {
                    isSuccess=SendPrintTaskItemToPrinterTextMode(taskItem);
                }
                else if (taskItem.TextFormat.print_mode == "Image")
                {
                    isSuccess=SendPrintTaskItemToPrinterImageMode(taskItem);
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }
        /// <summary>
        /// 发送打印任务项到打印机,以文本模式进行打印
        /// </summary>
        /// <param name="taskItem">打印任务项</param>
        /// <returns></returns>
        private bool SendPrintTaskItemToPrinterTextMode(PrintTaskItemV1d0 taskItem)
        {
            bool isSuccess = false;
            try
            {
                if (taskItem.content_text.Length == 0) return false;
                //asc 字符串打印模式
                byte AscPrintMode = GetAscPrintMode(taskItem);
                SendByteCommand(PrinterCmdUtilsV1d0.AscFontPrintMode(AscPrintMode));
                //多字节字符打印模式
                byte MbcsPrintMode = GetMbcsPrintMode(taskItem);                 
                SendByteCommand(PrinterCmdUtilsV1d0.MbcsFontPrintMode(MbcsPrintMode));
                //对齐方式
                SetAlignOfPrinter(taskItem);
                
                SendStringToPrinter(taskItem.content_text, taskItem.TextFormat.encoding_name);
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }
        /// <summary>
        /// 得到asc字符的打印模式配置字节
        /// </summary>
        /// <returns></returns>
        private byte GetAscPrintMode(PrintTaskItemV1d0 taskItem)
        {
            byte ascPrintMode = 0;
            if (taskItem.TextFormat.is_double_height)
            {
                //asc
                ascPrintMode = (byte)(ascPrintMode + 16);
            }
            //倍宽
            if (taskItem.TextFormat.is_double_width)
            {
                //asc
                ascPrintMode = (byte)(ascPrintMode + 32);
            }
            //asc粗体
            if (taskItem.TextFormat.is_bold)
            {
                ascPrintMode = (byte)(ascPrintMode + 8);
            }
            return ascPrintMode;
        }
        /// <summary>
        /// 得到多字节字符的打印模式配置字节 多字节字符的打印不支持粗体
        /// </summary>
        /// <returns></returns>
        private byte GetMbcsPrintMode(PrintTaskItemV1d0 taskItem)
        {
            byte mbcsPrintMode = 0;
            //倍高
            if (taskItem.TextFormat.is_double_height)
            {
                //多字节字符
                mbcsPrintMode = (byte)(mbcsPrintMode + 8);
            }
            //倍宽
            if (taskItem.TextFormat.is_double_width)
            {
                //多字节字符
                mbcsPrintMode = (byte)(mbcsPrintMode + 4);
            }
            return mbcsPrintMode;
        }
        /// <summary>
        /// 设置打印机的文本打印对齐方式
        /// </summary>
        /// <param name="align">对齐方式</param>
        /// <returns></returns>
        private bool SetAlignOfPrinter(PrintTaskItemV1d0 taskItem)
        {
            bool result = false;
            try
            {
                if (taskItem.TextFormat.align == "Left")
                {
                    SendByteCommand(PrinterCmdUtilsV1d0.alignLeft());
                }
                else if (taskItem.TextFormat.align == "Center")
                {
                    SendByteCommand(PrinterCmdUtilsV1d0.alignCenter());
                }
                else if (taskItem.TextFormat.align == "Right")
                {
                    SendByteCommand(PrinterCmdUtilsV1d0.alignRight());
                }
                result = true;
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return result;
        }
        /// <summary>
        /// 发送打印任务项到打印机,以图像模式
        /// </summary>
        /// <param name="taskItem">打印任务项</param>
        /// <returns></returns>
        private bool SendPrintTaskItemToPrinterImageMode(PrintTaskItemV1d0 taskItem)
        {
            bool isSuccess = false;
            try
            {
                if (taskItem.content_text.Length == 0) return false;
                //待写入位图的字体
                Bitmap printBitmap = PrintTextInfoV1d0.GetAutoHeightBitmapFromText(taskItem);
                isSuccess = SendBitmpToPrinter(printBitmap);
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return isSuccess;
        }
        
        /// <summary>
        /// 对位图格式进行检查，宽度必须400像素，高度必须是8的整数倍
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public bool CheckBitmapFormat(Bitmap bitmap)
        {
            bool result = false;
            try
            {
                if (bitmap != null)
                {
                    int width = bitmap.Width;
                    int height = bitmap.Height;
                    if (width != 400) result = false;
                    else result = true;
                    if (height % 8 != 0) result = false;
                    else result = true;
                }
            }
            catch (Exception ex)
            {
                SimpleLoger.Instance.Error(ex);
            }
            return result;
        }

        public int checkInt(int value)
        {
            return value;
        }
    }
    /// <summary>
    /// 幂运算 接口
    /// </summary>
    public interface ICheckBitmapFormat //专为 需用mock替代的对象 写一个接口
    {
        int  CheckBitmapFormat(int value);
    }
}
